<?php

declare(strict_types=1);

namespace App\Repositories;

use App\Models\UserModel;

class UserRepository
{
    private const ROLE_FIELD = 'role';

    /**
     * Obtiene solo las columnas que se deben visualizar.
     */
    private function getColumns(): array
    {
        return ['id', 'email', 'username', 'role_id', 'fullname', 'is_active', 'created_at', 'updated_at'];
    }

    /**
     * Constructor de la clase.
     */
    public function __construct(private UserModel $userModel = new UserModel) {}

    /**
     * Consulta el id de un usuario desde el valor de una columna.
     */
    public function findIdByColumn(string $column, mixed $value): ?string
    {
        $this->userModel->reset();

        $user = $this->userModel->select('id')
            ->eq($column, $value)
            ->find();

        if (! $this->userModel->isHydrated()) {
            return null;
        }

        return $user->id;
    }

    /**
     * Registra la información de un usuario.
     */
    public function insert(array $data): UserModel
    {
        $this->userModel->reset();

        $this->userModel->copyFrom($data);
        $this->userModel->insert();

        return $this->findByIdWithDetails($this->userModel->id);
    }

    /**
     * Consulta la información detallada de un usuario desde su id.
     */
    public function findByIdWithDetails(string $id): ?UserModel
    {
        $this->userModel->reset();

        $user = $this->userModel->select(...$this->getColumns())
            ->eq('id', $id)
            ->find();

        if (! $this->userModel->isHydrated()) {
            return null;
        }

        return $this->withRole($user);
    }

    /**
     * Agrega el rol de un usuario.
     */
    private function withRole(UserModel $user): UserModel
    {
        $user->setCustomData(self::ROLE_FIELD, $user->role);
        unset($user->role_id);

        return $user;
    }
}
